﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace UnitControls {
    /// <summary>
    /// Interaction logic for LengthInput.xaml
    /// </summary>

    public class Unit {
        string m_name;
        double m_ratio;
        double m_zero;

        [Category( "Common" )]
        public string name {
            get { return m_name; }
            set { m_name = value; }
        }

        [Category( "Common" )]
        public double ratio {
            get { return m_ratio; }
            set { m_ratio = value; }
        }

        [Category( "Common" )]
        public double zero {
            get { return m_zero; }
            set { m_zero = value; }
        }
        // 
    }

    public partial class DblInput : UserControl {
        private double m_Value; // Reference unit

        public bool freeze = true;

        private ObservableCollection<Unit> m_Units = new ObservableCollection<Unit>();
        public ObservableCollection<Unit> units {
            get { return m_Units; }
            set { m_Units = value; }
        }
        
        private int m_selectedUnit = 1;
        [Category( "Common" )]
        public int selectedUnit {
            get { return UnitBox.SelectedIndex; }
            set {
                m_selectedUnit = value;
                UnitBox.SelectedIndex = m_selectedUnit;
            }
        }

        [Category( "Common" )]
        public double Value {
            get { return m_Value; }
            set {
                m_Value = value;
                UpdateTextBox();
            }
        }

        private event EventHandler m_OnChange;
        public event EventHandler OnChange {
            add {
                lock ( this ) {
                    m_OnChange += value;
                }
            }
            remove {
                lock ( this ) {
                    m_OnChange -= value;
                }
            }
        }

        public DblInput() {
            InitializeComponent();
            m_Units.CollectionChanged += m_Units_CollectionChanged;
            UnitBox.SelectionChanged += UnitBox_SelectionChanged;
            //UpdateTextBox();
            //freeze = false;
        }

        public void UpdateTextBox() {
            if ( InputBox.IsFocused ) return;
            if ( freeze ) return;
            //if ( !this.IsEnabled ) return;
            //if ( !this.IsLoaded ) return;

            InputBox.Text = ((m_Value - m_Units[m_selectedUnit].zero) * m_Units[m_selectedUnit].ratio).ToString();

            if ( this.IsLoaded && this.IsEnabled && m_OnChange != null )
                m_OnChange( this, new EventArgs() );
        }

        public void UpdateComboBox() {
            UnitBox.SelectionChanged -= UnitBox_SelectionChanged;

            while ( UnitBox.Items.Count > 0 )
                UnitBox.Items.RemoveAt( 0 );

            foreach ( Unit u in m_Units )
                UnitBox.Items.Add( u.name );
            UnitBox.SelectedIndex = m_selectedUnit;

            UnitBox.SelectionChanged += UnitBox_SelectionChanged;

            UpdateTextBox();
        }

        void m_Units_CollectionChanged( object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e ) {
            UpdateComboBox();
        }

        private void UnitBox_SelectionChanged( object sender, SelectionChangedEventArgs e ) {
            m_selectedUnit = UnitBox.SelectedIndex;
            UpdateTextBox();
        }

        private void BtnMinus_Click( object sender, RoutedEventArgs e ) {
            Value -= (1.0 / m_Units[m_selectedUnit].ratio);
            UpdateTextBox();
        }

        private void BtnPlus_Click( object sender, RoutedEventArgs e ) {
            Value += (1.0 / m_Units[m_selectedUnit].ratio);
            UpdateTextBox();
        }

        private void InputBox_LostFocus( object sender, RoutedEventArgs e ) {
            if ( InputBox.Text.Length == 0 ) {
                Value = 0;
                return;
            }

            try {
                Value = ( double.Parse( InputBox.Text ) / m_Units[UnitBox.SelectedIndex].ratio ) + m_Units[m_selectedUnit].zero ;
            } catch (Exception exc) {
                UpdateTextBox();
            }
        }
    }
}
